class Barline
   
  # Attributes
  attr_reader :mfc_class_name
  attr_reader :mfc_class_schema

  attr_reader :position
  attr_accessor :rehearsal_sign
  attr_accessor :key_signature
  attr_accessor :time_signature

  # Constants
  DEFAULT_POSITION = 0
  DEFAULT_DATA = 0x00000000
   
  MIN_REPEAT_COUNT = 2
  MAX_REPEAT_COUNT = 24  
   
  BAR = 0
  DOUBLE_BAR = 1
  FREE_TIME_BAR = 2
  REPEAT_START = 3
  OPEN_BAR = 3
  REPEAT_END = 4
  DOUBLE_BAR_FINE = 5
   
  TYPE_MASK = 0x000000e0
  REPEAT_COUNT_MASK = 0x0000001f
   
  def initialize(position=DEFAULT_POSITION, type=nil, repeat_count=nil)
    mfc_class_name = "CMusicBar"
    mfc_class_schema = 1

    @data = DEFAULT_DATA   
     
    @key_signature = KeySignature.new
    @time_signature = TimeSignature.new
    @rehearsal_sign = RehearsalSign.new
    
    position=(position)
    type=(type)
    repeat_count=(repeat_count)
  end
   
  def valid_position?(position)
    return ((position >= 0) && (position <= 255))
  end
   
  def position=(position)
    return false unless valid_position?(position)
    @position = position
    return true
  end
   
  def valid_type?(type)
    return (type <= DOUBLE_BAR_FINE)
  end
   
  def type
    return (((@data & TYPE_MASK) >> 5))
  end

  def type=(type)
    @data &= ~TYPE_MASK
    @data |= (type << 5)     
    return true
  end
   
  def bar?
    return (type == BAR)
  end
   
  def double_bar?
    return (type == DOUBLE_BAR)
  end
   
  def free_time_bar?
    return (type == FREE_TIME_BAR)
  end
   
  def repeat_start?
    return (type == REPEAT_START)
  end
   
  def repeat_end?
    return (type == REPEAT_END)
  end
   
  def double_bar_fine?
    return (type == DOUBLE_BAR_FINE)
  end
   
  def valid_repeat_count?(repeat_count)
    return (((repeat_count >= MIN_REPEAT_COUNT) && (repeat_count <= MAX_REPEAT_COUNT)) || (repeat_count == 0))
  end
   
  def repeat_count
    return ((@data & REPEAT_COUNT_MASK))
  end

  def repeat_count=(repeat_count)
    return false unless valid_repeat_count?(repeat_count)
    @data &= ~REPEAT_COUNT_MASK
    @data |= repeat_count    
    return true
  end

  def barline_data(type, repeat_count)
    return false unless type=(type)
    return false unless repeat_count=(repeat_count)
    return true
  end
   
  def barline_data=(type, repeat_count)
    type = type()
    repeat_count = repeat_count()
  end
  
  def do_serialize(stream)
    write_byte(stream, @position)
    write_byte(stream, @data)
    @key_signature.do_serialize(stream)
    @time_signature.do_serialize(stream)
    @rehearsal_sign.do_serialize(stream)
    return true
  end
   
  def do_deserialize(stream)
    @position = read_byte(stream)
    @data = read_byte(stream)    
    @key_signature = KeySignature.new
    @time_signature = TimeSignature.new
    @rehearsal_sign = RehearsalSign.new         
    @key_signature.do_deserialize(stream)   
    @time_signature.do_deserialize(stream)   
    @rehearsal_sign.do_deserialize(stream)   
    return true
  end

end
